#include "Star.h"

c_particle::c_particle(void (*draw_pixel)(int x, int y, unsigned int rgb),
                       void (*fill_rect)(int x0, int y0, int x1, int y1,
                                         unsigned int rgb)) {
  m_op.draw_pixel = draw_pixel;
  m_op.fill_rect = fill_rect;

  c_display display =
      c_display(NULL, UI_WIDTH, UI_HEIGHT, UI_WIDTH, UI_HEIGHT, 2, 1, &m_op);
  m_surface = display.alloc_surface((void *)1, Z_ORDER_LEVEL_0);
  m_surface->set_active(true);
  m_surface->fill_rect(0, 0, UI_WIDTH - 1, UI_HEIGHT - 1, 0, Z_ORDER_LEVEL_0);

  m_stars = (c_star *)malloc(sizeof(c_star) * UI_STAR_SIZE);
}

c_particle::~c_particle() { free(m_stars); }

void c_particle::draw() {
  DWORD millis = GetTickCount();

  if (millis - m_lastDrawMillis > 33) {
    m_lastDrawMillis = millis;
    for (size_t i = 0; i < UI_STAR_SIZE; ++i) {
      m_stars[i].move(m_surface);
    }
  }
}

c_star::c_star() { initialize(); }

void c_star::initialize() {
  m_x = m_start_x = rand() % UI_WIDTH;
  m_y = m_start_y = rand() % UI_HEIGHT;
  m_size = 1;
  m_x_factor = UI_WIDTH;
  m_y_factor = UI_HEIGHT;
  m_size_factor = 1;
}

void c_star::move(c_surface *surface) {
  surface->fill_rect(m_x, m_y, m_x + m_size - 1, m_y + m_size - 1, 0,
                     Z_ORDER_LEVEL_0);  // clear star footprint

  m_x_factor -= 6;
  m_y_factor -= 6;
  m_size += m_size / 20;
  if (m_x_factor < 1 || m_y_factor < 1) {
    return initialize();
  }
  if (m_start_x > (UI_WIDTH / 2) && m_start_y > (UI_HEIGHT / 2)) {
    m_x =
        (UI_WIDTH / 2) + (UI_WIDTH * (m_start_x - (UI_WIDTH / 2)) / m_x_factor);
    m_y = (UI_HEIGHT / 2) +
          (UI_HEIGHT * (m_start_y - (UI_HEIGHT / 2)) / m_y_factor);
  } else if (m_start_x <= (UI_WIDTH / 2) && m_start_y > (UI_HEIGHT / 2)) {
    m_x =
        (UI_WIDTH / 2) - (UI_WIDTH * ((UI_WIDTH / 2) - m_start_x) / m_x_factor);
    m_y = (UI_HEIGHT / 2) +
          (UI_HEIGHT * (m_start_y - (UI_HEIGHT / 2)) / m_y_factor);
  } else if (m_start_x > (UI_WIDTH / 2) && m_start_y <= (UI_HEIGHT / 2)) {
    m_x =
        (UI_WIDTH / 2) + (UI_WIDTH * (m_start_x - (UI_WIDTH / 2)) / m_x_factor);
    m_y = (UI_HEIGHT / 2) -
          (UI_HEIGHT * ((UI_HEIGHT / 2) - m_start_y) / m_y_factor);
  } else if (m_start_x <= (UI_WIDTH / 2) && m_start_y <= (UI_HEIGHT / 2)) {
    m_x =
        (UI_WIDTH / 2) - (UI_WIDTH * ((UI_WIDTH / 2) - m_start_x) / m_x_factor);
    m_y = (UI_HEIGHT / 2) -
          (UI_HEIGHT * ((UI_HEIGHT / 2) - m_start_y) / m_y_factor);
  }

  if (m_x < 0 || (m_x + m_size - 1) >= UI_WIDTH || m_y < 0 ||
      (m_y + m_size - 1) >= UI_HEIGHT) {
    return initialize();
  }
  surface->fill_rect(m_x, m_y, m_x + m_size - 1, m_y + m_size - 1,
                     GL_RGB(255, 255, 255), Z_ORDER_LEVEL_0);  // draw star
}